(function ($, window, document, undefined) {

$(document).ready(function() {
	
	$klass = $.klass;
	$proto = $klass.prototype;
	$trait = $.trait;
	Trait = $klass.Trait;
	
	module("Wiki Klass");
	
	test("", function() {
		
	// A Simple class
		Counter = $.klass({
		  init: function( start ) {
			this.count = start;
		  },
		  isLimitReached: function( limit ) {
			return this.count >= limit;
		  },
		  increment: function( ) {
			this.count++;
			return this.count;
		  },
		  toString: function() {
			return "Count: " + this.count + " !";
		  }
		});
		
	// Instantiating and using class
		counter = new Counter( 0 );
		strictEqual(counter.increment( ), 1, 'counter.increment( )');  // => 1
		strictEqual(counter.count, 1, 'counter.count');  // => 1
		strictEqual(counter.isLimitReached( 0 ), true, 'counter.isMoreThan( 0 )');  // => true
		strictEqual(counter.isLimitReached( 100 ), false, 'counter.isMoreThan( 100 )');  // => false
		
		strictEqual(counter instanceof Counter, true, 'counter instanceof Counter');  // => true
		strictEqual(counter.init === Counter, true, 'counter.init === Counter');  // => true
		
	// Subclass with inheritance
		LimitedCounter = $.klass( Counter, {  // Inherit from Counter
		  init: function( start, limit ) {
			this._super( arguments, start );  // Call the super method (which is "init", the constructor of Counter)
			this.limit = limit;
		  },
		  isLimitReached: function( ) {
			// Call the super method (ie: the method "isLimitReached" from the super-class Counter):
			return this._super( arguments, this.limit ) ? "Limit reached !" : "Nope.";
		  },
		  increment: function( ) {
			// Call the method "isLimitReached" from the super-class Counter:
			if ( !this._super( "isLimitReached", arguments, this.limit ) ) {
				 // Call the super method (ie: the method "increment" from the super-class Counter):
				this._super( arguments );
			}
			return this.toString();
		  }
		});
		
		limitedCounter1 = new LimitedCounter( 0, 0 );  // Limit already reached
		strictEqual(limitedCounter1.isLimitReached( ), "Limit reached !", 'limitedCounter1.isLimitReached( )');  // => "Limit reached !"
		strictEqual(limitedCounter1.increment( ), "Count: 0 !", 'limitedCounter1.increment( )');  // => "Count: 0 !"
		
		limitedCounter2 = new LimitedCounter( 10, 100 );  // Limit already reached
		strictEqual(limitedCounter2.isLimitReached( ), "Nope.", 'limitedCounter2.isLimitReached( )');  // => "Nope."
		strictEqual(limitedCounter2.increment( ), "Count: 11 !", 'limitedCounter2.increment( )');  // => "Count: 11 !"
		
		strictEqual(limitedCounter1 instanceof LimitedCounter, true, 'limitedCounter1 instanceof LimitedCounter');  // => true
		strictEqual(limitedCounter1 instanceof Counter, true, 'limitedCounter1 instanceof Counter');  // => true
		strictEqual(LimitedCounter._super === Counter, true, 'LimitedCounter._super === Counter');  // => true
		strictEqual(Counter._super, undefined, 'Counter._super');  // => undefined
		
	// Static variables
		MyKlass = $.klass({
		  init: function() {
			MyKlass.nbInstances++;  // modify the static variable.
		  },
		  getNbInstances: function( ) {
			return MyKlass.nbInstances;  // access the static variable
		  },
		  _klass: {  // Everything defined here (not only functions) will become a static variable (or class variable).
			nbInstances: 0,
			resetNbInstances: function() {
			  this.nbInstances = 0;  // Here 'this' refers to MyKlass.
			}
		  }
		});
		
		n1 = new MyKlass();
		strictEqual(n1.getNbInstances(), 1, 'n1.getNbInstances()');  // => 1
		strictEqual(n1._klass, undefined, 'n1._klass');  // => undefined
		
		new MyKlass(); new MyKlass(); new MyKlass();
		n2 = new MyKlass();
		strictEqual(n1.getNbInstances(), 5, 'n1.getNbInstances()');  // => 5
		strictEqual(n2.getNbInstances(), 5, 'n2.getNbInstances()');  // => 5
		MyKlass.resetNbInstances();
		strictEqual(n2.getNbInstances(), 0, 'n2.getNbInstances()');  // => 0
	});
});

})(jQuery, window, window.document);